package com.hlkj.warboot.configurer.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.Random;

/**
 * @Description: TODO 字符串工具类
 * @Author: 李星 lixing_java@163.com
 * @Date: 2019/10/10 21:21
 */
public class StrUtil {
    private static String algorithm = "AES"; // TODO 加密算法，AES、ARCFOUR、Blowfish、DES、DESede、HmacMD5、RC2、HmacSHA1、HmacSHA256、HmacSHA384、HmacSHA512
    private static String algorithmProvider = "AES/CBC/PKCS5Padding"; // TODO 加解密算法/工作模式/填充方式(PKCS5Padding与js的Pkcs7一致)

    public static void main(String[] args) throws Exception {
//        String work = "QWE_asd.hn"; // fyygIWjXVedYHII7dbNPfw==
//        String work = "QWE_fgh.hn"; // u+Cbk5kbxdbB+rOW7bX4dg==
//        String work = "QWE_jkl.hn"; // YWOk0muGyTO0Zsz6YiK8Gw==
//        String work = "QWE_zxc.hn"; // gVUTKN5TyxWsAqiwZSPI2A==
//        String work = "QWE_vbn.hn"; // 0hvEcvTIxZWNmjaPL55g+A==
//        String work = "QWE_qaz.hn"; // RdWd/6VbmJRthnoEHmq/GA==
//        String work = "QWE_wsx.hn"; // sME7PW24zmymdjyAQg2DnQ==
//        String work = "QWE_edc.hn"; // YCo75H1yt5FuP8UEXggRKQ==
//        String work = "QWE_rfv.hn"; // bg8Z+Vr8ZesiflznzigS/g==
//        String work = "QWE_tgb.hn"; // K+3Jv+rflQUFhp9qA2TZxQ==

//        String work = "li123456"; // ht6lmoWlZTtO6Y0jWyV4ew==
//        System.out.println(encrypt(work,"A1a1B1b1C1c1D1d1", "E1e1F1f1G1g1H1h1"));
//
//        String a = "XQI/5CC+ft6JjEZ/XpT3GzGJeJVeLBZMHqd3di/D8o0YGnuDXSsuRinUtxiIkGFCxuvVYlO+SZOTj4DWkiZttyTQji7mNzZ5vXtdxdnteHo7nXNz5FFjP6+OVjM7T8azb/v+QlUtT2Zg85zR8+Tbysk5ZY4WHFE0kcdtCg2N0fA=";
//        System.out.println(a.length());

        BigDecimal bigDecimal = new BigDecimal("1000000000");
            String m = new DecimalFormat("#,###").format(bigDecimal.longValue());
            System.out.println(m);
    }

    /*
     * @Description TODO AES/CBC/PKCS5Padding对称加密
     * @Author 李星
     * @Date 2019/8/20 14:13
     * @Param [word 待加密字符串, key 密钥(十六位的十六进制数：a1b1c1d1e1f1g1h1)，动态生成最佳, iv 密钥偏移量(十六位的十六进制数)，动态生成最佳]
     * @return java.lang.String
     */
    public static String encrypt(String word, String key, String iv) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key.getBytes(), algorithm); // SecretKey
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); // IvParameterSpec
        //
        Cipher cipher = Cipher.getInstance(algorithmProvider);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        byte[] cipherBytes = cipher.doFinal(word.getBytes(StandardCharsets.UTF_8));
        return Base64.encodeBase64String(cipherBytes);
    }

    /*
     * @Description TODO AES/CBC/PKCS5Padding对称解密
     * @Author 李星
     * @Date 2019/10/10 21:25
     * @Param [word 待解密字符串, key 密钥(十六位的十六进制数：a1b1c1d1e1f1g1h1)，动态生成最佳, iv 密钥偏移量(十六位的十六进制数)，动态生成最佳]
     * @return java.lang.String
     */
    public static String decrypt(String world, String key, String iv) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key.getBytes(), algorithm); // SecretKey
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); // IvParameterSpec
        //
        Cipher cipher = Cipher.getInstance(algorithmProvider);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
        byte[] decryptBytes = cipher.doFinal(Base64.decodeBase64(world));
        return new String(decryptBytes);
    }

    /*
     * @Description TODO 判断字符都是否有效
     * @Author 李星
     * @Date 2019/2/15 23:35
     * @Param [str]
     * @return java.lang.Boolean
     */
    public static Boolean isEffective(String str) {
        return str != null && str.trim().length() > 0 && !str.equalsIgnoreCase("null");
    }

    /*
     * @Description 字符串数组转化成以逗号分隔的字符串
     * @Author 李星
     * @Date 2020/2/28 9:27
     * @Param [strs]
     * @return java.lang.String
     */
    public static String stringArrayToString(String[] stringArray) {
        if (stringArray == null || stringArray.length == 0) {
            return null;
        }
        StringBuilder stringBuffer = new StringBuilder();
        for (String s : stringArray) {
            stringBuffer.append(s).append(",");

        }
        String resultStr = stringBuffer.toString();
        if (resultStr.endsWith(",")) {
            resultStr = resultStr.substring(0, resultStr.length() - 1);
        }
        return resultStr;
    }

    /*
     * @Description TODO 生成指定长度的字符串
     * @Author 李星
     * @Date 2019/7/27 15:14
     * @Param [type Number（生成数字），String（生成字符），mix（生成数字和字符）, length 长度]
     * @return java.lang.String
     */
    public static String genRandomStr(String type, int length) {
        String allChar;
        if ("Number".equals(type)) {
            allChar = "0123456789";
        } else if ("String".equals(type)) {
            allChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        } else {
            allChar = "0123456789abcdefghjklmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
        }
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < length; i++) {
            buffer.append(allChar.charAt(new Random().nextInt(((allChar.length())))));
        }
        return buffer.toString();
    }

    /*
     * @Description TODO 字符串首字母大写
     * @Author 李星
     * @Date 2019/2/15 23:36
     * @Param [str]
     * @return java.lang.String
     */
    public String upperCaseForFirst(String str) {
        byte[] items = str.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String( items );
    }

    /*
     * @Description TODO 字符串首字母小写
     * @Author 李星
     * @Date 2019/2/15 23:36
     * @Param [str]
     * @return java.lang.String
     */
    public String lowerCaseForFirst(String str) {
        byte[] items = str.getBytes();
        items[0] = (byte) ((char) items[0] - 'A' + 'a');
        return new String( items );
    }

    /*
     * @Description TODO 求两个字符串数组的并集，利用set的元素唯一性
     * @Author 李星
     * @Date 2019/2/15 23:36
     * @Param [arr1, arr2]
     * @return java.lang.String[]
     */
//    public String[] union(String[] arr1, String[] arr2) {
//        Set<String> set = new HashSet<>();
//        Collections.addAll( set, arr1 );
//        Collections.addAll( set, arr2 );
//        String[] result = {};
//        return set.toArray( result );
//    }

    /*
     * @Description TODO 求两个字符串数组的交集
     * @Author 李星
     * @Date 2019/2/15 23:36
     * @Param [arr1, arr2]
     * @return java.lang.String[]
     */
//    public String[] intersect(String[] arr1, String[] arr2) {
//        Map<String, Boolean> map = new HashMap<>();
//        LinkedList<String> list = new LinkedList<>();
//        for (String str : arr1) {
//            if (!map.containsKey( str )) {
//                map.put( str, Boolean.FALSE );
//            }
//        }
//        for (String str : arr2) {
//            if (map.containsKey( str )) {
//                map.put( str, Boolean.TRUE );
//            }
//        }
//        for (Map.Entry<String, Boolean> e : map.entrySet()) {
//            if (e.getValue().equals( Boolean.TRUE )) {
//                list.add( e.getKey() );
//            }
//        }
//        String[] result = {};
//        return list.toArray( result );
//    }

    /*
     * @Description TODO 求两个字符串数组的差集
     * @Author 李星
     * @Date 2019/2/15 23:36
     * @Param [arr1, arr2]
     * @return java.lang.String[]
     */
//    public String[] minus(String[] arr1, String[] arr2) {
//        LinkedList<String> list = new LinkedList<>();
//        LinkedList<String> history = new LinkedList<>();
//        String[] longerArr = arr1;
//        String[] shorterArr = arr2;
//        //找出较长的数组来减较短的数组
//        if (arr1.length > arr2.length) {
//            longerArr = arr2;
//            shorterArr = arr1;
//        }
//        for (String str : longerArr) {
//            if (!list.contains( str )) {
//                list.add( str );
//            }
//        }
//        for (String str : shorterArr) {
//            if (list.contains( str )) {
//                history.add( str );
//                list.remove( str );
//            } else {
//                if (!history.contains( str )) {
//                    list.add( str );
//                }
//            }
//        }
//        String[] result = {};
//        return list.toArray( result );
//    }

    /** 将输入流转化成字节数组 */
    public static byte[] getByteArray(InputStream inputStream) throws IOException {
        byte[] data = null;
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            data = byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return data;
    }

}
